<template>
    <div v-if="state.show" class="loading-box" :style="state.loadingBoxStyle">
        <div class="mask" :style="{ background: state.maskBackground }"></div>
        <div class="loading-content-box">
            <n-spin
                v-if="state.show"
                :size="state.size"
                :rotate="state.rotate"
                :stroke="state.stroke"
            >
                <template #description>
                    <div
                        v-if="state.description !== false"
                        :style="{ color: state.textColor }"
                        class="tip"
                    >
                        {{ state.description }}
                    </div>
                </template>
            </n-spin>
        </div>
    </div>
</template>

<script setup lang="ts">
import { defineExpose, reactive } from "vue";
import { NSpin } from "naive-ui";

const state = reactive({
    show: false,
    description: "加载中..." as any,
    rotate: true,
    size: "medium" as any,
    stroke: "#18A058",
    maskBackground: "rgba(255, 255, 255, 0.5)",
    textColor: "#18A058",
    loadingBoxStyle: {},
});

type ILoadingInfo = {
    show?: boolean;
    description?: any;
    size?: string;
    rotate: boolean;
    maskBackground?: string;
    textColor?: string;
    loadingBoxStyle?: string;
};

// 更新loading信息
const updateLoading = (loadingInfo: ILoadingInfo) => {
    const {
        show,
        description,
        maskBackground,
        size,
        rotate,
        textColor,
        loadingBoxStyle,
        stroke,
    } = loadingInfo as any;
    state.show = show || state.show;
    // false： 不显示  true、不传：显示默认
    state.description =
        description === false
            ? false
            : description === true || !!description === false
            ? state.description
            : description;

    state.size = size || state.size;
    state.rotate = rotate || state.rotate;
    state.stroke = stroke || state.stroke;
    state.textColor = textColor || state.textColor;
    state.maskBackground = maskBackground || state.maskBackground;
    state.loadingBoxStyle = loadingBoxStyle || state.loadingBoxStyle;
};

defineExpose({
    updateLoading,
});
</script>
<style scoped>
.loading-box {
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    height: 100%;
    overflow: hidden;
    z-index: 19999;
}

.n-spin {
    color: #ccc;
}

.mask {
    width: 100%;
    height: 100%;
}

.loading-content-box {
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}

.tip {
    font-size: 14px;
    margin-top: 8px;
}
</style>
